package com.oa.core.utils;

import org.bytedeco.javacv.FFmpegFrameGrabber;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;

import java.awt.Image;


import org.bytedeco.javacpp.opencv_core.IplImage;
import org.bytedeco.javacv.Frame;
import org.csource.fastdfs.StorageClient;
import org.springframework.web.multipart.MultipartFile;

/**
 * 文件上传工具类
 */
public class FileUtil {

    /**
     * 文件分段大小
     */
    private final static int section_size =1024 * 500 * 15;

    /**
     * 单文件上传
     * @param file
     * @param filePath
     * @param fileName
     * @throws Exception
     */
    public static void uploadFile(byte[] file, String filePath, String fileName) throws Exception{

        File targetFile = new File(filePath);
        if(!targetFile.exists()){
            targetFile.mkdirs();
        }
        FileOutputStream out = new FileOutputStream(filePath+fileName);
        out.write(file);
        out.flush();
        out.close();
    }

    /**
     * 获取指定视频的帧并保存为图片至指定目录
     * @param videofile  源视频文件路径
     * @param framefile  截取帧的图片存放路径
     * @throws Exception
     */
    public static void fetchFrame(String videofile, String framefile)
            throws Exception {
        long start = System.currentTimeMillis();
        File targetFile = new File(framefile);
        FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videofile);
        ff.start();
        int lenght = ff.getLengthInFrames();
        int i = 0;
        Frame f = null;
        while (i < lenght) {
            // 过滤前5帧，避免出现全黑的图片，依自己情况而定
            f = ff.grabFrame();
            if ((i > 5) && (f.image != null)) {
                break;
            }
            i++;
        }
        IplImage img = f.image;
        int owidth = img.width();
        int oheight = img.height();
        // 对截取的帧进行等比例缩放
        int width = 800;
        int height = (int) (((double) width / owidth) * oheight);
        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
        bi.getGraphics().drawImage(f.image.getBufferedImage().getScaledInstance(width, height, Image.SCALE_SMOOTH),
                0, 0, null);
        ImageIO.write(bi, "jpg", targetFile);
        //ff.flush();
        ff.stop();
        System.out.println(System.currentTimeMillis() - start);
    }



    public static byte[] File2byte(File file){
        byte[] buffer = null;
        try
        {
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1)
            {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return buffer;
    }

    //上传一个0字节，获取一个fileid
    public static String upload_file5_1(StorageClient client, MultipartFile file, String suffix) throws Exception {
        long start = System.currentTimeMillis();
        String[] results = client.upload_appender_file(new byte[]{},suffix,null);

        System.err.println("group_name: " + results[0] + ", remote_filename: "
                + results[1]);
        System.err.println("upload zero byte cost time "+(System.currentTimeMillis()-start)/1000.0);

        String group_name = results[0];
        String remote_filename = results[1];
        upload_file(client,file,group_name,remote_filename);

        System.err.println("uoload cost time "+(System.currentTimeMillis()-start)/1000.0);
        return group_name+"/"+remote_filename;
    }

    // 将文件按照单位大小分次追加到指定的fileid
    public static long upload_file(StorageClient client,MultipartFile file,String group_name, String remote_filename)
            throws Exception {
        long length = file.getSize();
        int size = 0;
        byte[] buff = new byte[section_size];
        InputStream is = file.getInputStream();
        long start = System.currentTimeMillis();
        while (size < length) {
            long temp = System.currentTimeMillis();
            int readcount = is.read(buff, 0,
                    (length - size) < buff.length ? (int) (length - size)
                            : buff.length);
            System.out.println("readcount:" + readcount);
            // 3次尝试上传都失败则不上传该文件，并记录已上传的大小，下次上传可以skip已上传大小后，再上传
            int count = 0;
            while (true) {
                int result = -1;
                try {
                    byte[] newbuffer;
                    if (readcount < buff.length) {
                        newbuffer = new byte[readcount];
                        System.arraycopy(buff, 0, newbuffer, 0, readcount);
                        result = client.append_file(group_name, remote_filename,
                                newbuffer);
                    } else {
                        result = client.append_file(group_name, remote_filename,
                                buff);
                    }

                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                count++;
                if (result == 0) {
                    break;
                }
                if (count >= 3) {
                    return size;
                }
            }
            size += readcount;
            System.err.println("upload " + readcount + " byte cost time "
                    + (System.currentTimeMillis() - temp) / 1000.0);
            System.err.println("upload " + size + " byte cost time "
                    + (System.currentTimeMillis() - start) / 1000.0);
        }
        return length;
    }


    //上传一个0字节，获取一个fileid
    public static String upload_file5_1(StorageClient client, File file, String suffix) throws Exception {
        long start = System.currentTimeMillis();
        String[] results = client.upload_appender_file(new byte[]{},suffix,null);

        System.err.println("group_name: " + results[0] + ", remote_filename: "
                + results[1]);
        System.err.println("upload zero byte cost time "+(System.currentTimeMillis()-start)/1000.0);

        String group_name = results[0];
        String remote_filename = results[1];
        upload_file(client,file,group_name,remote_filename);

        System.err.println("uoload cost time "+(System.currentTimeMillis()-start)/1000.0);
        return group_name+"/"+remote_filename;
    }

    // 将文件按照单位大小分次追加到指定的fileid
    public static long upload_file(StorageClient client,File file,String group_name, String remote_filename)
            throws Exception {
        long length = file.length();
        int size = 0;
        byte[] buff = new byte[section_size];
        InputStream is = new FileInputStream(file);
        long start = System.currentTimeMillis();
        while (size < length) {
            long temp = System.currentTimeMillis();
            int readcount = is.read(buff, 0,
                    (length - size) < buff.length ? (int) (length - size)
                            : buff.length);
            System.out.println("readcount:" + readcount);
            // 3次尝试上传都失败则不上传该文件，并记录已上传的大小，下次上传可以skip已上传大小后，再上传
            int count = 0;
            while (true) {
                int result = -1;
                try {
                    byte[] newbuffer;
                    if (readcount < buff.length) {
                        newbuffer = new byte[readcount];
                        System.arraycopy(buff, 0, newbuffer, 0, readcount);
                        result = client.append_file(group_name, remote_filename,
                                newbuffer);
                    } else {
                        result = client.append_file(group_name, remote_filename,
                                buff);
                    }

                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                count++;
                if (result == 0) {
                    break;
                }
                if (count >= 3) {
                    return size;
                }
            }
            size += readcount;
            System.err.println("upload " + readcount + " byte cost time "
                    + (System.currentTimeMillis() - temp) / 1000.0);
            System.err.println("upload " + size + " byte cost time "
                    + (System.currentTimeMillis() - start) / 1000.0);
        }
        if (is!=null){
            is.close();
        }
        return length;
    }

    /**
     * 读取文件内容，作为字符串返回
     */
    public static String readFileAsString(String filePath) throws IOException {
        File file = new File(filePath);
        if (!file.exists()) {
            throw new FileNotFoundException(filePath);
        }

        if (file.length() > 1024 * 1024 * 1024) {
            throw new IOException("File is too large");
        }

        StringBuilder sb = new StringBuilder((int) (file.length()));
        // 创建字节输入流
        FileInputStream fis = new FileInputStream(filePath);
        // 创建一个长度为10240的Buffer
        byte[] bbuf = new byte[10240];
        // 用于保存实际读取的字节数
        int hasRead = 0;
        while ( (hasRead = fis.read(bbuf)) > 0 ) {
            sb.append(new String(bbuf, 0, hasRead));
        }
        fis.close();
        return sb.toString();
    }

    /**
     * 根据文件路径读取byte[] 数组
     */
    public static byte[] readFileByBytes(String filePath) throws IOException {
        File file = new File(filePath);
        if (!file.exists()) {
            throw new FileNotFoundException(filePath);
        } else {
            ByteArrayOutputStream bos = new ByteArrayOutputStream((int) file.length());
            BufferedInputStream in = null;

            try {
                in = new BufferedInputStream(new FileInputStream(file));
                short bufSize = 1024;
                byte[] buffer = new byte[bufSize];
                int len1;
                while (-1 != (len1 = in.read(buffer, 0, bufSize))) {
                    bos.write(buffer, 0, len1);
                }

                byte[] var7 = bos.toByteArray();
                return var7;
            } finally {
                try {
                    if (in != null) {
                        in.close();
                    }
                } catch (IOException var14) {
                    var14.printStackTrace();
                }

                bos.close();
            }
        }
    }

}
